﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MagicArena.framework.physics.util
{
    public struct Vector2
    {
        public float X
        {
            get;
            private set;
        }
        public float Y
        {
            get;
            private set;
        }
        public Vector2(float x, float y) :this()
        {
            X = x;
            Y = y;
        }
        public float DistSquared(Vector2 p)
        {
            float xx = (this.X - p.X);
            xx *= xx;
            float yy = this.Y - p.Y;
            yy *= yy;
            return xx + yy;
        }
        public Vector2 UnitVector(Vector2 p)
        {
            //TODO Make more efficient unit vector calculation
            float d = DistSquared(p);
            d = (float)Math.Sqrt(d);
            float x = p.X - X;
            float y = p.Y - Y;

            return new Vector2(x / d, y / d);
        }
    }

    public struct Rectangle
    {
        public Vector2 UpperLeft
        {
            get;
            private set;
        }
        public float X
        {
            get
            {
                return UpperLeft.X;
            }
            
        }
        public float Y
        {
            get
            {
                return UpperLeft.Y;
            }
        }
        public Vector2 Size
        {
            get;
            private set;
        }
        public float Width
        {
            get
            {
                return Size.X;
            }
        }
        public float Height
        {
            get
            {
                return Size.Y;
            }
        }
        public Rectangle(float x, float y, float width, float height) : this()
        {
            UpperLeft = new Vector2(x, y);
            Size = new Vector2(width, height);
        }

        
    }
    public struct Circle
    {
        public Vector2 Center
        {
            private set;
            get;
        }
        public float X
        {
            get
            {
                return Center.X;
            }
        }
        public float Y
        {
            get
            {
                return Center.Y;
            }
        }
        public float Radius
        {
            get;
            private set;
        }
        public Circle(float x, float y, float radius) : this()
        {
            Center = new Vector2(x, y);
            Radius = radius;
        }
    }

    public class ShapeIntersector{
        public static bool DoIntersect(Rectangle r1, Rectangle r2)
        {
            float xx = r1.X - r2.X;
            xx = xx < 0 ? -2 * xx : xx * 2;
            float yy = r1.Y - r2.Y;
            yy = yy < 0 ? -2 * yy : yy * 2;
            return (xx < (r1.Width + r2.Width) && yy < (r1.Height + r2.Height));
        }
        public static bool DoIntersect(Circle c1, Circle c2)
        {
            double dist2 = c1.Center.DistSquared(c2.Center);
            double r2 = c1.Radius + c2.Radius;
            r2 *= r2;
            return dist2 > r2;
        }
        public static bool DoIntersect(Rectangle r, Circle c)
        {
            float closestX = c.X;
            float closestY = c.Y;

            if (c.X < r.X)
            {
                closestX = r.X;
            }
            else if (c.X > r.X + r.Width)
            {
                closestX = r.X + r.Width;
            }

            if (c.Y < r.Y)
            {
                closestY = r.Y;
            }
            else if (c.Y > r.Y + r.Height)
            {
                closestY = r.Y + r.Height;
            }

            return c.Center.DistSquared(new Vector2(closestX, closestY)) < c.Radius * c.Radius;
        }
    }
}
